package com.gtan.hogpen.benchmark

import javax.sql.DataSource
import java.util.concurrent.CountDownLatch
import java.text.NumberFormat
import akka.actor.{Actor, ActorSystem, Props, ActorRef}
import scala.concurrent.{ExecutionContext, Await, Future}
import concurrent.duration._
import com.gtan.hogpen.{HogpenConnection, HogpenDataSource}

object HogpenBenchmark {
  val Pass = 1000
  import ExecutionContext.Implicits.global
  val totalLatch = new CountDownLatch(Pass)

  def main(args: Array[String]) {
    val system = ActorSystem("HogpenConnectionPool")
    val dataSource = new HogpenDataSource(system)
    val startMillis = System.currentTimeMillis()
    for (i <- 0 until Pass){
      p0(dataSource, "hogpen", 50)
    }
    totalLatch.await()
    val millis = System.currentTimeMillis() - startMillis
    System.out.println(s"total: $millis")
    system.shutdown()
  }

  def p0(dataSource: DataSource, name: String, threadCount: Int) {
    val startLatch = new CountDownLatch(1)
    val endLatch = new CountDownLatch(threadCount)
    val dumpLatch = new CountDownLatch(1)
    val LOOP_COUNT = Pass * 1 * 1 / threadCount
    val looper = (0 until LOOP_COUNT).toList
    val threads = Array.fill(threadCount) {
      val thread = new Thread {
        override def run() {
          try {
            startLatch.await()

            val all = Future.traverse(looper){ _ =>
              val conn = dataSource.getConnection.asInstanceOf[HogpenConnection]
              conn.benchmark
            }
            Await.result(all, 1 second)
          } catch {
            case ex: Throwable => ex.printStackTrace()
          }
          endLatch.countDown()

//          try {
//            dumpLatch.await()
//          } catch {
//            case e: InterruptedException => e.printStackTrace()
//          }
        }
      }
      thread.start()
    }
    val startMillis = System.currentTimeMillis()

//    val startYGC = TestUtil.getYoungGC
//    val startFullGC = TestUtil.getFullGC
    startLatch.countDown()
    endLatch.await()

//    val blockedCount = 0
//    val waitedCount = 0
//    for (threadInfo <- threadInfoArray) {
//      blockedCount += threadInfo.getBlockedCount
//      waitedCount += threadInfo.getWaitedCount
//    }

    val millis = System.currentTimeMillis() - startMillis
//    val ygc = TestUtil.getYoungGC - startYGC
//    val fullGC = TestUtil.getFullGC - startFullGC

    println(s"thread $threadCount $name millis : ${NumberFormat.getInstance.format(millis)}; " +
//      s"YGC $ygc FGC $fullGC " +
//      s"blocked ${NumberFormat.getInstance.format(blockedCount)} waited ${NumberFormat.getInstance.format(waitedCount)} " +
//      s"physicalConn ${phisicalConnStat.get}"
        "")
    totalLatch.countDown()
  }
}
